class_name PlayerData
extends UnitBaseData

@export var level: int = 1
@export var exp: int = 0
@export var hold_item_data: ItemData = null
@export var items: Array[ItemData] = []

@export var equip_item: ItemData = null:
	set(value): 
		if value != equip_item:
			equip_item = value
			if GlobalSignals:
				GlobalSignals.player_info_changed.emit()
	get:
		return equip_item
		
@export var equip_cards: Array[ItemData] = []

# little key num
@export var little_key_num: int = 0
@export var big_key_num: int = 0

# bullet
@export var bullets_data: Array[BulletData] = []

# additional attack
@export var additional_attack: int = 0

# additional defense
@export var additional_defense: int = 0

@export var additional_life: int = 0


func get_base_life():
	var player_config = config as PlayerConfig
	return config.base_life * (1.0 + player_config.life_growth * (level - 1))
	

func get_max_life():
	return get_base_life() + additional_life


func get_anti_search():
	var result = 0
	if equip_item:
		result += equip_item.item_config.anti_search
	return result
	

func get_base_defense() -> int:
	var player_config = config as PlayerConfig
	return config.base_defense * (1.0 + player_config.defense_growth * (level - 1))	
	

func get_defense() -> int:
	var defense = get_base_defense() + additional_defense
	return defense
	

func get_defense_with_equip() -> int:
	var defense = get_defense()
	if equip_item:
		defense += equip_item.item_config.equip_defense
	return defense


func get_base_attack() -> int:
	var player_config = config as PlayerConfig
	return config.base_attack * (1.0 + player_config.attack_growth * (level - 1))


func get_attack() -> int:
	return get_base_attack() + additional_attack
	

func get_equip_defense() -> int:
	if not equip_item: return 0
	return equip_item.item_config.equip_defense
	
	
func get_hold_item_attack() -> int:
	if not hold_item_data: return 0
	return hold_item_data.item_config.attack


func get_hold_item_critical_rate():
	if not hold_item_data: return 0
	return hold_item_data.item_config.critical_rate


func get_hold_item_critical_bonus():
	if not hold_item_data: return 0
	return hold_item_data.item_config.critical_bonus


func get_anti_knockback():
	return config.base_anti_knockback


func reduce_bullet(bullet_type: BulletData.BulletType, count: int = 1):
	for bullet_data in bullets_data:
		if bullet_data.bullet_type == bullet_type:
			bullet_data.count -= count
			if bullet_data.count <= 0:
				bullet_data.count = 0
				

func get_bullet_count(bullet_type: BulletData.BulletType):
	for bullet_data in bullets_data:
		if bullet_data.bullet_type == bullet_type:
			return bullet_data.count


func get_next_level_need_exp():
	var player_config = config as PlayerConfig
	return player_config.exp_for_level(level + 1)
	
	
func get_push_item_power():
	var result = 0
	
	if hold_item_data.item_config is MeleeWeaponConfig:
		var melee_weapon_config = hold_item_data.item_config as MeleeWeaponConfig
		result = melee_weapon_config.push_drop_item_power
	
	return result
	

func add_exp(amount):
	exp += amount
	if exp >= get_next_level_need_exp():
		level += 1
		
		var new_max_hp = get_max_life()
		var diff = new_max_hp - max_hp
		max_hp = new_max_hp
		hp += diff
